package com.hmall.order.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hmall.client.ItemClient;
import com.hmall.client.AddressClient;
import com.hmall.common.pojo.*;
import com.hmall.order.mapper.OrderDetailMapper;
import com.hmall.order.mapper.OrderLogisticsMapper;
import com.hmall.order.mapper.OrderMapper;
import com.hmall.order.service.IOrderService;
import com.hmall.order.web.dto.OrderDTO;
import com.hmall.pojo.Item;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.UUID;

@Service
@Slf4j
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Resource
    private ItemClient itemClient;

    @Resource
    private AddressClient userClient;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 前端用户传的订单数据参数
     *
     * @param orderDTO
     * @return
     */
    @Override
    @GlobalTransactional

    public Long createOrder(OrderDTO orderDTO) {
        Order order = new Order();
        //1）根据雪花算法生成订单id
        Long orderId = IdWorker.getId();
        order.setId(orderId);
        //2）商品微服务提供FeignClient，实现根据id查询商品的接口
        //3）根据itemId查询商品信息
        Item item = itemClient.findById(orderDTO.getItemId());
        //4）基于商品价格、购买数量计算商品总价：totalFee
        Long totalFee = item.getPrice() * orderDTO.getNum();
        order.setTotalFee(totalFee);
        //5）封装Order对象，初识status为未支付
        order.setPaymentType(orderDTO.getPaymentType());

        order.setCreateTime(new Date());
        order.setCommentTime(new Date());
        //TODO 后续封装为常量
        order.setStatus(1);
        order.setUpdateTime(new Date());
        //TODO 后续从请求头中获取
        order.setUserId(2L);
        //6）将Order写入数据库tb_order表中
        int orderRowCount = orderMapper.insert(order);
        //7）将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        orderDetail.setCreateTime(new Date());
        orderDetail.setUpdateTime(new Date());
        orderDetail.setImage(item.getImage());
        orderDetail.setItemId(item.getId());
        orderDetail.setNum(orderDTO.getNum());
        orderDetail.setPrice(totalFee);
        orderDetail.setSpec(item.getSpec());
        orderDetail.setName(item.getName());
        int rowCount = orderDetailMapper.insert(orderDetail);
        //8）将user-service的根据id查询地址接口封装为FeignClient
        //9）根据addressId查询user-service服务，获取地址信息
        Integer addressId = orderDTO.getAddressId();
        Address address = userClient.findAddressById(addressId);
        //10）将地址封装为OrderLogistics对象，写入tb_order_logistics表
        OrderLogistics orderLogistics = new OrderLogistics();
        orderLogistics.setOrderId(orderId);
        orderLogistics.setLogisticsNumber("114514");
        orderLogistics.setLogisticsCompany("黑马物流");
        orderLogistics.setContact(address.getContact());
        orderLogistics.setMobile(address.getMobile());
        orderLogistics.setProvince(address.getProvince());
        orderLogistics.setCity(address.getCity());
        orderLogistics.setTown(address.getTown());
        orderLogistics.setStreet(address.getStreet());
        orderLogistics.setCreateTime(new Date());
        orderLogistics.setUpdateTime(new Date());
        int orderLogisticsRowCount = orderLogisticsMapper.insert(orderLogistics);
        //11）在item-service提供减库存接口，并编写FeignClient
        //12）调用item-service的减库存接口
        Integer itemClientRowCount = itemClient.updateByNum(orderDTO.getItemId(),orderDTO.getNum());

        //发送延迟队列
        Message message = MessageBuilder
                .withBody(orderId.toString().getBytes(StandardCharsets.UTF_8))
                .setHeader("x-delay", 1000 * 20)
                .build();
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("delay.direct","delay",message,correlationData);
        log.info("发送延迟队列成功 时间："+ LocalDateTime.now());
        return orderId;
    }
}
